package org.interfaceadaptation.parameter.expression.converter;

import java.util.HashMap;
import java.util.Map;

import org.interfaceadaptation.parameter.expression.converter.impl.ToStringConverter;
import org.interfaceadaptation.parameter.expression.converter.impl.ValueOfConverter;

public class Converters {
	
	private static Converters instance;
	
	public static Converters getInstance() {
		return instance;
	}

	
	static {
		instance = new Converters();
		instance.addConverter(new ValueOfConverter(String.class,Byte.class));
		instance.addConverter(new ToStringConverter(Byte.class));
		instance.addConverter(new ValueOfConverter(String.class,Short.class));
		instance.addConverter(new ToStringConverter(Short.class));
		instance.addConverter(new ValueOfConverter(String.class,Integer.class));
		instance.addConverter(new ToStringConverter(Integer.class));
		instance.addConverter(new ValueOfConverter(String.class,Long.class));
		instance.addConverter(new ToStringConverter(Long.class));
		instance.addConverter(new ValueOfConverter(String.class,Double.class));
		instance.addConverter(new ToStringConverter(Double.class));
		instance.addConverter(new ValueOfConverter(String.class,Float.class));
		instance.addConverter(new ToStringConverter(Float.class));
		
	}
	
	

    private  Map<ConverterPair, Converter> converters = new HashMap<ConverterPair, Converter>();

    public void addConverter(Converter converter) {
        converters.put(new ConverterPair(converter), converter);
    }

    public Converter getConverter(Class<?> from, Class<?> to) {
        return converters.get(new ConverterPair(from, to));
    }

    private static class ConverterPair {
        private Class<?> from;
        private Class<?> to;

        public ConverterPair(Class<?> from, Class<?> to) {
            this.from = from;
            this.to = to;
        }
        
        public ConverterPair(Converter converter) {
            this.from = converter.getFromClass();
            this.to = converter.getToClass();
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((from == null) ? 0 : from.hashCode());
            result = prime * result + ((to == null) ? 0 : to.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            ConverterPair other = (ConverterPair) obj;
            if (from == null) {
                if (other.from != null)
                    return false;
            } else if (!from.equals(other.from))
                return false;
            if (to == null) {
                if (other.to != null)
                    return false;
            } else if (!to.equals(other.to))
                return false;
            return true;
        }

    }

}
